package cz.spock.core.controller;

import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import cz.spock.core.service.AccountService;
import cz.spock.core.service.RegistrationService;
import cz.spock.exception.DatabaseException;
import cz.spock.exception.InvalidDataException;
import cz.spock.exception.InvalidInputException;

@Controller
public class AccountController extends BaseController {
    
    @Autowired
    private AccountService accService;
    @Autowired
    private RegistrationService regService;
    
    /**
     * URL: /ajax/account
     * Method: POST
     * 
     * Ajax service for creating new account (and related AccountSecurity),
     * must contain valid hash in order to register new user. (hash should be obtained from previous call)
     * (email is obtained from database by hash)
     * 
     * Params:
     * - hash - string, not null
     * - login - string, not null
     * - password - string, not null
     * - roles - string - possible delimeters [,] [;] [SPACE], default value is ROLE_USER
     * 
     * Error messages:
     * - 41x invalid input data
     * - 500 internal error
     * - 42x data problem - email is already used
     * 
     * Status: not tested
     * 
     * @param request
     * @param response
     */
    // TODO create admin alternative for this service
    @RequestMapping(value = "/ajax/account", method = RequestMethod.POST)
    public void createAccount(HttpServletRequest request, HttpServletResponse response) {
        // verify hash, get email, login, password...
        String hash = this.readParamAsString(request, "hash");
        if(!regService.verifyRegistrationLink(hash)) {
            // TODO permission denied handler
            log.info("hash not valid");
            return;
        }
        String email = regService.getEmailForLink(hash);
        String login = this.readParamAsString(request, "login");
        String pass = this.readParamAsString(request, "password");
        String rolesS = this.readParamAsString(request, "roles");

        // parse roles
        String delimeters = "[,; ]";
        List<String> roles = null;
        if(rolesS != null) roles = Arrays.asList(rolesS.split(delimeters));

        // calls service
        try {
            accService.createAccount(login, email);
            accService.createAccountSecurity(login, pass, roles, true);
        } catch(InvalidInputException e) {
            sendJson(response, accService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(InvalidDataException e) {
            sendJson(response, accService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(DatabaseException e) {
            sendJson(response, accService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(Exception e) {
            log.severe("Exception in RegistrationController method createAccount: " + e.getMessage());
            sendJson(response, accService.errorToJson("Internal error.", 500));
            return;            
        }
        // success message
        log.finest("registration request done");
        // TODO delete hash
        sendJson(response, accService.responseToJson(null));
    }
    
    /**
     * returns all accounts
     * 
     * @param request
     * @param response
     */
    @RequestMapping(value = "/ajax/account", method = RequestMethod.GET)
    public void getAccounts(HttpServletRequest request, HttpServletResponse response) {
        
    }
    
    @RequestMapping(value = "/ajax/account/{id}", method = RequestMethod.GET)
    public void getAccount(HttpServletRequest request, HttpServletResponse response) {
        
    }
    
    
}
